/**
 *  TextMash - simple IDE for Clojure
 *  
 *  Copyright (C) 2010 Aleksander Naszko
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package pl.olek.textmash.workspace;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JDialog;
import javax.swing.text.StyledEditorKit;

/**
 * 
 * @author anaszko
 *
 */
public class FindDialog extends JDialog {

	private static final long serialVersionUID = 1L;
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JButton jButton3;
    private javax.swing.JButton jButton4;
    private javax.swing.JButton jButton5;
    private javax.swing.JCheckBox jCheckBox1;
    private javax.swing.JCheckBox jCheckBox2;
    private javax.swing.JComboBox jComboBox1;
    private javax.swing.JComboBox jComboBox2;
    private javax.swing.JComboBox jComboBox3;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    Workspace workspace;
    int searchingPosition;
    boolean searchingEnd;
    int lastSearch;
    int lastPosition;
    
    public String getFind(){
    	Object obj = jComboBox2.getSelectedItem();
    	if (obj == null) {
    		return null;
    	}
    	return obj.toString();
    }
    
    public String getReplaceTo(){
    	return null;
    }
    
    public String getMode(){
    	return null;
    }
    
    public boolean isCaseSensitive(){
    	return false;
    }
    
    public boolean isFromCaretPosition(){
    	return false;
    }
    
    ActionListener replaceAll = new ActionListener() {

		@Override
		public void actionPerformed(ActionEvent e) {
			searchingEnd = false;
			
			workspace.getTextPane().undo.setManualEdit(true);
			
			do {
				
				find.actionPerformed(e);
				
				if (!searchingEnd) {
					replace.actionPerformed(e);
				} else {
					break;
				}
				
			} while(workspace.getTextPane().getDocument().getLength() > 0);
			
			workspace.getTextPane().undo.setManualEdit(false);
			workspace.getTextPane().undoAction.updateUndoState();
			workspace.getTextPane().redoAction.updateRedoState();
		}
    	
    	
    };
    
    ActionListener replace = new ActionListener() {
		
		@Override
		public void actionPerformed(ActionEvent e) {
			boolean caseInsensitive = !jCheckBox1.isSelected();
			
			String find = jComboBox2.getSelectedItem().toString();
			
			if (find != null && caseInsensitive) {
				find = find.toLowerCase();
			}
			
			String text = workspace.getTextPane().getSelectedText();
			
			if (text != null && caseInsensitive) {
				text = text.toLowerCase();
			}
			
			String replaceTo = jComboBox3.getSelectedItem().toString();
			
			if (find != null && text != null && find.equals(text)) {
				workspace.getTextPane().replaceSelection(replaceTo);
			} else {		
				workspace.getTextPane().getAction(StyledEditorKit.beepAction).actionPerformed(e);
			}
			
		}
	};
	 ActionListener findPrev = new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {

				boolean caseInsensitive = !jCheckBox1.isSelected();
				
				String find = jComboBox2.getSelectedItem().toString();
				
				if (caseInsensitive) {
					find = find.toLowerCase();
				}

				String text = workspace.getTextPane().getTextForSearching(
						caseInsensitive);
				
				boolean freashSearch = false;
				
				if (lastSearch == 0) {
					freashSearch = true;
					
					searchingPosition = workspace.getTextPane().getDocument().getLength();
				} else if (lastSearch == 1) {
					
					searchingPosition = lastPosition - 1;
				}
				lastSearch = -1;
				int from = searchingPosition;

				if (jCheckBox2.isSelected() && freashSearch) {
					from = workspace.getTextPane().getCaretPosition();
				}
				
				int a = text.lastIndexOf(find, from);
				
				if (a != -1 && find != null && find.length() > 0) {
					workspace.getTextPane().select(a, a + find.length());
					searchingPosition = a - 1;
					lastPosition = a;
				} else {
					lastPosition = -1;
					searchingPosition = workspace.getTextPane().getDocument().getLength();
					workspace.getTextPane().setCaretPosition(searchingPosition);			
					workspace.getTextPane().getAction(StyledEditorKit.beepAction).actionPerformed(e);
					
					searchingEnd = true;
				}
				
			}
		};
    ActionListener find = new ActionListener() {
		
		@Override
		public void actionPerformed(ActionEvent e) {

			boolean caseInsensitive = !jCheckBox1.isSelected();
			
			String find = jComboBox2.getSelectedItem().toString();
			
			if (caseInsensitive) {
				find = find.toLowerCase();
			}

			String text = workspace.getTextPane().getTextForSearching(
					caseInsensitive);
			

			boolean freashSearch = false;
			
			if (lastSearch == 0) {
				freashSearch = true;
				
				searchingPosition = 0;
			}else if (lastSearch == -1) {
				searchingPosition = lastPosition + 1;
			}
			lastSearch = 1;
			int from = searchingPosition;

			if (jCheckBox2.isSelected() && freashSearch) {
				from = workspace.getTextPane().getCaretPosition();
			}
			
			int a = text.indexOf(find, from);
			
			if (a != -1 && find != null && find.length() > 0) {
				workspace.getTextPane().select(a, a + find.length());
				searchingPosition = a + 1;
				lastPosition = a;
			} else {
				workspace.getTextPane().setCaretPosition(0);			
				workspace.getTextPane().getAction(StyledEditorKit.beepAction).actionPerformed(e);
				searchingPosition = 0;
				lastPosition = workspace.getTextPane().getDocument().getLength() + 1; 
				searchingEnd = true;
			}
			

		}
	};
    
	public FindDialog(final Workspace workspace) {
		super(workspace, "Find");
		this.workspace = workspace;
		setModal(false);
		setResizable(false);
		workspace.getTextPane().requestFocus();
		
		 jButton1 = new javax.swing.JButton();
	        jButton2 = new javax.swing.JButton();
	        jButton3 = new javax.swing.JButton();
	        jButton4 = new javax.swing.JButton();
	        jButton5 = new javax.swing.JButton();
	        jComboBox1 = new javax.swing.JComboBox();
	        jCheckBox1 = new javax.swing.JCheckBox();
	        jCheckBox2 = new javax.swing.JCheckBox();
	        jLabel1 = new javax.swing.JLabel();
	        jComboBox2 = new javax.swing.JComboBox();
	        jLabel2 = new javax.swing.JLabel();
	        jComboBox3 = new javax.swing.JComboBox();

	        setName("Form"); // NOI18N
	       
	        jButton1.setText("Replace All"); // NOI18N
	        jButton1.setName("jButton1"); // NOI18N
	        jButton1.addActionListener(replaceAll);

	        jButton2.setText("Replace"); // NOI18N
	        jButton2.setName("jButton2"); // NOI18N
	        jButton2.addActionListener(replace);

	        jButton3.setText("Replace and Find"); // NOI18N
	        jButton3.setName("jButton3"); // NOI18N
	        jButton3.addActionListener(new ActionListener() {
				
				@Override
				public void actionPerformed(ActionEvent e) {
					replace.actionPerformed(e);
					find.actionPerformed(e);
				}
			});
	        jButton4.setText("Find Previous"); // NOI18N
	        jButton4.setName("jButton4"); // NOI18N
	        jButton4.addActionListener(findPrev);
	        
	        jButton5.setText("Find Next"); // NOI18N
	        jButton5.setName("jButton5"); // NOI18N
	        jButton5.addActionListener(find);

	        jComboBox1.setModel(new javax.swing.DefaultComboBoxModel(new String[] { /*"Regular Expression",*/ "Containing" /*, "Whole Word", "Starting with", "Ending with", "Soundex", "Levenshtein distance (<= 3)"*/ }));
	        jComboBox1.setName("jComboBox1"); // NOI18N

	        jCheckBox1.setText("Case Sensitive"); // NOI18N
	        jCheckBox1.setName("jCheckBox1"); // NOI18N

	        jCheckBox2.setText("From Caret Position"); // NOI18N
	        jCheckBox2.setName("jCheckBox2"); // NOI18N

	        jLabel1.setText("Find:"); // NOI18N
	        jLabel1.setName("jLabel1"); // NOI18N

	        jComboBox2.setEditable(true);
	        jComboBox2.setModel(new javax.swing.DefaultComboBoxModel(new String[] { ""}));
	        jComboBox2.setName("jComboBox2"); // NOI18N
	        jComboBox2.addActionListener(new ActionListener() {
				
				@Override
				public void actionPerformed(ActionEvent e) {
					lastSearch = 0;
				}
			});
	        
	        
	        jLabel2.setText("Replace to:"); // NOI18N
	        jLabel2.setName("jLabel2"); // NOI18N

	        jComboBox3.setEditable(true);
	        jComboBox3.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "" }));
	        jComboBox3.setName("jComboBox3"); // NOI18N

	        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
	        this.setLayout(layout);
	        layout.setHorizontalGroup(
	            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
	            .addGroup(layout.createSequentialGroup()
	                .addContainerGap()
	                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
	                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
	                        .addComponent(jButton1)
	                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 3,  Short.MAX_VALUE)
	                        .addComponent(jButton2)
	                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 3,  Short.MAX_VALUE)
	                        .addComponent(jButton3)
	                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 3,  Short.MAX_VALUE)
	                        .addComponent(jButton4)
	                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 3,  Short.MAX_VALUE)
	                        .addComponent(jButton5/*, javax.swing.GroupLayout.DEFAULT_SIZE, 79, Short.MAX_VALUE*/))
	                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
	                        .addGap(54)
	                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
	                            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
	                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
	                                    .addComponent(jLabel1)
	                                    .addComponent(jLabel2))
	                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
	                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
	                                    .addComponent(jComboBox3, 0, 150, Short.MAX_VALUE)
	                                    .addComponent(jComboBox2, 0, 150, Short.MAX_VALUE)))
	                            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
	                                .addComponent(jCheckBox2)
	                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
	                                .addComponent(jCheckBox1)
	                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
	                                .addComponent(jComboBox1, javax.swing.GroupLayout.PREFERRED_SIZE, 180, javax.swing.GroupLayout.PREFERRED_SIZE)))))
	                .addContainerGap())
	        );
	        layout.setVerticalGroup(
	            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
	            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
	                .addGap(8)
	                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
	                    .addComponent(jComboBox2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
	                    .addComponent(jLabel1))
	                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 3, Short.MAX_VALUE)
	                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
	                    .addComponent(jComboBox3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
	                    .addComponent(jLabel2))
	                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 3, Short.MAX_VALUE)
	                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
	                    .addComponent(jComboBox1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
	                    .addComponent(jCheckBox1)
	                    .addComponent(jCheckBox2))
	                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 3, Short.MAX_VALUE)
	                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
	                    .addComponent(jButton1)
	                    .addComponent(jButton2)
	                    .addComponent(jButton3)
	                    .addComponent(jButton4)
	                    .addComponent(jButton5))
	                .addGap(12))
	        );


	        pack();
	        setAlwaysOnTop(false);
		setLocationRelativeTo(workspace); 
		setVisible(true);
	}
	
}
